﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Celeriq.DataCore.EFDAL;
using Celeriq.DataCore.EFDAL.Entity;
using Celeriq.Utilities;

namespace Celeriq.Server.Interfaces
{
    public static class ConfigHelper
    {
        private static DateTime _lastUpdate = DateTime.MinValue;
        private static List<Celeriq.DataCore.EFDAL.Entity.ConfigurationSetting> _settings = null;
        private static readonly object _syncObject = new object();

        #region Constructors

        static ConfigHelper()
        {
            Refresh();
        }

        public static void Refresh()
        {
            try
            {
                lock (_syncObject)
                {
                    //Load all settings from database
                    using (var context = new DataCoreEntities())
                    {
                        _settings = context.ConfigurationSetting.ToList();
                        _lastUpdate = DateTime.Now;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        public static void SetSetting(int id, string value)
        {
            lock (_syncObject)
            {
                using (var context = new DataCoreEntities())
                {
                    var item = context.ConfigurationSetting.FirstOrDefault(x => x.ID == id);
                    if (item != null)
                    {
                        item.Value = value;
                        context.SaveChanges();
                    }
                }
            }
            Refresh();
        }

        public static void SetSetting(int id, int value)
        {
            SetSetting(id, value.ToString());
        }

        #endregion

        #region Setting Methods

        public static IEnumerable<ConfigurationSetting> AllSettings
        {
            get
            {
                lock (_syncObject)
                {
                    if (DateTime.Now.Subtract(_lastUpdate).TotalSeconds > 20)
                    {
                        Refresh();
                    }
                    return _settings;
                }
            }
        }

        private static string GetValue(string name)
        {
            return GetValue(name, string.Empty);
        }

        private static string GetValue(string name, string defaultValue)
        {
            var q = AllSettings.FirstOrDefault(x => x.Name.ToLower() == name.ToLower());
            if (q == null) return defaultValue;
            else return q.Value;
        }

        private static int GetValue(string name, int defaultValue)
        {
            int retVal;
            if (int.TryParse(GetValue(name, string.Empty), out retVal))
                return retVal;
            return defaultValue;
        }

        private static bool GetValue(string name, bool defaultValue)
        {
            bool retVal;
            if (bool.TryParse(GetValue(name, string.Empty), out retVal))
                return retVal;
            return defaultValue;
        }

        private static void SetValue(string name, string value)
        {
            lock (_syncObject)
            {
                using (var context = new DataCoreEntities())
                {
                    var item = context.ConfigurationSetting.FirstOrDefault(x => x.Name == name);
                    if (item == null)
                    {
                        item = new ConfigurationSetting() { Name = name };
                        context.AddItem(item);
                    }
                    item.Value = value;
                    context.SaveChanges();
                    _lastUpdate = DateTime.MinValue;
                }
            }
        }

        private static void SetValue(string name, long value)
        {
            SetValue(name, value.ToString());
        }

        private static void SetValue(string name, bool value)
        {
            SetValue(name, value.ToString().ToLower());
        }

        #endregion

        #region Properties

        public static string PublicKey
        {
            get { return GetValue("PublicKey", string.Empty); }
            set { SetValue("PublicKey", value); }
        }

        public static string PrivateKey
        {
            get { return GetValue("PrivateKey", string.Empty); }
            set { SetValue("PrivateKey", value); }
        }

        public static int MaxRunningRepositories
        {
            get { return GetValue("MaxRunningRepositories", 0); }
            set { SetValue("MaxRunningRepositories", value); }
        }

        public static long MaxMemory
        {
            get { return GetValue("MaxMemory", 0); }
            set { SetValue("MaxMemory", value); }
        }

        public static int AutoDataUnloadTime
        {
            get { return GetValue("AutoDataUnloadTime", 0); }
            set { SetValue("AutoDataUnloadTime", value); }
        }

        public static KeyPair MasterKeys
        {
            get { return new KeyPair { PublicKey = ConfigHelper.PublicKey, PrivateKey = ConfigHelper.PrivateKey }; }
        }

        public static bool AllowCaching
        {
            get { return GetValue("AllowCaching", true); }
            set { SetValue("AllowCaching", value); }
        }

        #endregion

    }
}